//
//  YNMessagerManager.h
//  Messenger
//
//  Created by iOS on 15/2/6.
//  Copyright (c) 2015年 孙浪. All rights reserved.
//
//  消息接收分组
//

#import "YNMessagerManager.h"
#import "XMPPLogging.h"
#import "YNMessage.h"
#import "XMPPIDTracker.h"
#import "XMPPFramework.h"
#import <AudioToolbox/AudioToolbox.h>
#import "AitContactManagerTool.h"
#import "YNUser.h"
#import "YNMessageContactManager.h"
#import "YNContactManager.h"
#import "YNMessagerReceiveHandle.h"
#import "YNRemindManager.h"
#import "YNIMmanager.h"
#import "YNIMTool.h"
#import "YNIMFrameworkMacro.h"
#import "YNSessionOpenfireManager.h"

#if DEBUG
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN; // | XMPP_LOG_FLAG_TRACE;
#else
static const int xmppLogLevel = XMPP_LOG_LEVEL_OFF;
#endif


#define ReceiptTimeOut 60
#define NotificationTime   3

@interface YNMessagerManager ()<YNXMPPprotocol>
{
    XMPPIDTracker *xmppIDTracker;
    UILocalNotification *localNotification;
    NSDate              *lastDate;
    NSString *disgroupNo;
    
}
@property (nonatomic, strong)NSString *GroupNo;
@property (nonatomic, weak)id<YNXMPPprotocol> delegate;
@end

@implementation YNMessagerManager

-(instancetype)initWithDelegate:(id<YNXMPPprotocol>)delegate{
    self.delegate = delegate;
    [[YNIMmanager sharedInstance]addImDelegate:self];
    return [self initWithMessageDispatchQueue:NULL];
}

- (id)initWithMessageDispatchQueue:(dispatch_queue_t)queue
{
    if (self = [super initWithDispatchQueue:queue])
    {
        localNotification = [[UILocalNotification alloc] init];
        lastDate = [NSDate date];
    }
    return self;
}

- (BOOL)activate:(XMPPStream *)aXmppStream
{
    XMPPLogTrace();
    if ([super activate:aXmppStream])
    {
        XMPPLogVerbose(@"%@: Activated", THIS_FILE);
        xmppIDTracker = [[XMPPIDTracker alloc] initWithStream:xmppStream dispatchQueue:moduleQueue];
        return YES;
    }
    return NO;
}

-(void)dealloc{
    [[YNIMmanager sharedInstance]removeImDelegate:self];
}

- (void)deactivate
{
    [[YNIMmanager sharedInstance]removeImDelegate:self];
    XMPPLogTrace();
    [super deactivate];
}

#pragma - mark sendMessage 发送消息
/**HX** 发送回执消息 **/
- (void)sendReceiptMessage:(YNMessage*)aMessage type:(ReceiptMessageType)messageType{
    dispatch_block_t block = ^{ @autoreleasepool {
        
        XMPPMessage *msg = [XMPPMessage messageWithType:@"headline" to:[XMPPJID jidWithString:[NSString stringWithFormat:@"admin@%@", kXMPP_domain]]];
        NSXMLElement *body = [NSXMLElement elementWithName:[NSString stringWithFormat:@"received xmlns='urn:xmpp:receipts' id='%@' type='%@'",aMessage.toUserId,[NSString stringWithFormat:@"%ld",messageType]] stringValue:@""];
        [msg addAttributeWithName:@"from" stringValue:xmppStream.myJID.description];
        [msg addAttributeWithName:@"id" stringValue:aMessage.packetId];
        [msg addChild:body];
        
        debugLog(@"消息回执的消息内容:%@",msg);
        __weak typeof(multicastDelegate) weakmulticastDelegate = multicastDelegate;
        [xmppIDTracker addID:[msg elementID] block:^(XMPPIQ *iq, id <XMPPTrackingInfo> info){
            //回执
            [weakmulticastDelegate count];
            
        }timeout:ReceiptTimeOut];
        
        [xmppStream sendElement:msg];
    }};
    
    if (dispatch_get_specific(moduleQueueTag)) {
        block();
    }else {
        dispatch_async(moduleQueue, block);
    }
}

/**HX** 发送广播消息 **/
-(void)sendBroadcastMessage:(NSArray<NSString*>*)reciveUserIds body:(NSString*)body{
    if ([YNIMTool isEmptyArray:reciveUserIds]) {
        return;
    }
    dispatch_block_t block = ^{ @autoreleasepool {
        
        XMPPMessage *msg = [XMPPMessage messageWithType:@"chat" to:[XMPPJID jidWithString:[NSString stringWithFormat:@"specify@ynbroadcast.%@", kXMPP_domain]]];
        [msg addAttributeWithName:@"xmlns" stringValue:@"jabber:client"];
        [msg addAttributeWithName:@"from" stringValue:[NSString stringWithFormat:@"%@@%@/%@",[YNIMmanager sharedInstance].userImId,kXMPP_domain,kResource_Msg_Phone]];
        [msg addAttributeWithName:@"id" stringValue:[XMPPStream generateUUID]];
        
        NSXMLElement *subject = [NSXMLElement elementWithName:@"subject" stringValue:@"您有一条会议通知"];
        [msg addChild:subject];
        
        NSString*recipientJsonStr=[YNIMTool jsonStringWithObject:@{@"orgList":@[],@"userList":reciveUserIds}];
        NSXMLElement *recipient  = [NSXMLElement elementWithName:@"recipient " stringValue:recipientJsonStr];
        [recipient addAttributeWithName:@"xmlns" stringValue:@"com:yineng:broadcast"];
        [msg addChild:recipient ];
        
        NSString*bodyStr=body;
        NSXMLElement *body  = [NSXMLElement elementWithName:@"body " stringValue:bodyStr];
        [msg addChild:body ];
        
        //        NSXMLElement *sendTime   = [NSXMLElement elementWithName:@"sendTime " stringValue:[YNIMTool dateStringFromCurrentDate]];
        //        [sendTime addAttributeWithName:@"xmlns" stringValue:@"com:yineng:sendTime"];
        //        [msg addChild:sendTime ];
        
        /**HX** 不需要漫游的消息 需要在message里加入新的节点 <msgSaveWay xmlns="com:yineng: msgSaveWay ">0</ msgsaveway > **/
        NSXMLElement *filereceived = [NSXMLElement elementWithName:@"msgSaveWay" numberValue:@0];
        [filereceived setXmlns:@"com:yineng:msgSaveWay"];
        [msg addChild:filereceived];
        
        __weak typeof(multicastDelegate) weakmulticastDelegate = multicastDelegate;
        [xmppIDTracker addID:[msg elementID] block:^(XMPPIQ *iq, id <XMPPTrackingInfo> info){
            //回执
            [weakmulticastDelegate count];
            
        }timeout:ReceiptTimeOut];
        
        [xmppStream sendElement:msg];
    }};
    
    if (dispatch_get_specific(moduleQueueTag)) {
        block();
    }else {
        dispatch_async(moduleQueue, block);
    }
}

#pragma - mark sendMessage 发送消息
//发送消息-2018-05-21号黄旭修改，加入直播相关消息发送
- (void)sendMessage:(YNMessage *)aMassage
{
    dispatch_block_t block = ^{ @autoreleasepool {
        
        NSXMLElement *body = [NSXMLElement elementWithName:@"body" stringValue:aMassage.message];
        XMPPMessage *msg;
        if (aMassage.chatType == YNBubbleMessageChatTypeGroupChat || aMassage.chatType == YNBubbleMessageChatTypeDiscussion || aMassage.chatType == YNBubbleMessageChatTypeProjectTeamChat || aMassage.chatType == YNBubbleMessageChatTypeGroupChatVoice || aMassage.chatType == YNBubbleMessageChatTypeDiscussionVoice || aMassage.chatType == YNBubbleMessageChatTypeProjectTeamVoice)
        {
            NSString* roomJid = [NSString stringWithFormat:@"%@@conference.%@",aMassage.toUserId,kXMPP_domain];
            msg = [XMPPMessage messageWithType:@"groupchat" to:[XMPPJID jidWithString:roomJid]];
        }
        
        else
        {
            msg = [XMPPMessage messageWithType:@"chat" to:[XMPPJID jidWithString:[NSString stringWithFormat:@"%@@%@",aMassage.toUserId, kXMPP_domain]]];
        }
        
        [msg addAttributeWithName:@"from" stringValue:xmppStream.myJID.description];
        [msg addAttributeWithName:@"id" stringValue:aMassage.packetId];
        [msg addChild:body];
        [msg addAttributeWithName:@"xmlns" stringValue:@"jabber:client"];
        
        if (aMassage.chatType==YNBubbleMessageChatTypeFileWeChat) {
            /**HX** 是在文件接收回执消息，需要在message里加入新的节点 <filereceived xmlns=\"com:yineng:receipt\"></filereceived> **/
            NSXMLElement *filereceived = [NSXMLElement elementWithName:@"filereceived" xmlns:@"com:yineng:receipt"];
            [msg addChild:filereceived];
        }
        __weak typeof(multicastDelegate) weakmulticastDelegate = multicastDelegate;
        __block typeof(aMassage) weakMeassage = aMassage;
        __weak typeof (self) weakSelf = self;
        
        debugLog(@"发送的消息长这样=%@",msg);
        
        [xmppIDTracker addID:[msg elementID] block:^(XMPPIQ *iq, id <XMPPTrackingInfo> info){
            //回执
            NSUInteger count = [weakmulticastDelegate count];
            if (count)
            {
                [weakmulticastDelegate receiveReceiptStateWithIQ:iq aMesssage:weakMeassage];
            }
            else
            {
                //因为0表示并没有对象去实现代理, 所以只能这里将就处理了
                [weakSelf receiveReceiptWithIQ:iq aMessage:weakMeassage];
            }
            
        }timeout:ReceiptTimeOut];
        
        [xmppStream sendElement:msg];
    }};
    
    if (dispatch_get_specific(moduleQueueTag)) {
        block();
    }else {
        dispatch_async(moduleQueue, block);
    }
}


#pragma mark XMPPStream Delegate

//接受消息
-(void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{
    //撤回消息逻辑处理
    if (![YNIMTool isEmptyObject:message] && [message elementForName:@"unmark"] != nil)
    {
        [self messengerWithdrawunMarkInfowithMessage:message];
    }
    else
    {
        NSString *chatType = message.type;
        /**HX** 收到pc端发来的消息已读回执-解析消息 **/
        if ([chatType isEqualToString:@"headline"]) {
            
            [YNMessage covertJsonWithHTML:message.body];
            /*HX** 收到pc端发来的消息已读回执-解析消息 */
            NSXMLElement*nsxmlelement=[message elementForName:@"received"];
            XMPPMessage*xmMessage=[XMPPMessage messageFromElement:nsxmlelement];
            NSString*typeString= [[xmMessage attributeForName:@"type"] stringValue];
            NSString*idString=[[xmMessage attributeForName:@"id"] stringValue];
            if ([typeString integerValue]!=ReceiptMessageType_BroadcastMessage) {
                //二人会话、群、讨论组
                if (![YNIMTool isEmptyString:idString]) {
                    [YNMessageContactManager updateUnReadMessageNumberWithIdentify:idString];
                }
            }else{
                //更新本地该条广播为已读
                [YNMessageContactManager updateIsReadToReadInDatabaseWithPacketid:idString];
                //更新消息会话界面
                dispatch_async(dispatch_get_main_queue(), ^{
                    if ([self.delegate respondsToSelector:@selector(updateTheBroadcastReaedForId:)]) {
                        [self.delegate updateTheBroadcastReaedForId:idString];
                    }
                });
                //将会话列表的广播消息未读数减一
                [YNContactManager updateUserUnreadCountByOneWithUserNo:@"广播" isAddOne:NO];
                //清掉广播消息未读id记录数组里存的该条id
                [[YNIMmanager sharedInstance]clearBroadcastMsgId:idString];
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                if ([self.delegate respondsToSelector:@selector(updataRecentChatInterface)]) {
                    [self.delegate updataRecentChatInterface];
                }
            });
            return;
        }
        
        if ((message.body && message.subject == nil) || (message.body && message.subject))
        {
            NSArray *tempMsgList=nil;
            NSString *bodyString = [NSString stringWithFormat:@"%@",message.body];
            NSDictionary *messageBody = (NSDictionary*)[YNIMTool getJsonObjectFromJsonString:bodyString];
            NSString *action = [messageBody objectForKey:@"action"];
            NSArray *msgIdList = [messageBody objectForKey:@"msgIdList"];
            if (msgIdList != nil && [msgIdList count] > 0 && [action integerValue] == 1)
            {
                tempMsgList = msgIdList;
            }
            
            if (tempMsgList)
            {
                return;
            }
            
            YNMessage *msg = [[YNMessage alloc] initWithXMPPMessage:message messageSourceType:GroupMessageSourceType_online isFromSessionListLastMessage:NO];
            /**HX** 讨论组和群加入漫游后当我在本地发出一条信息时同时我会收一条同样的信息，这是应为我发出的这条消息后台会给群里每个人发这条消息，这里的每个人包括了自己，所以要过滤掉这个消息不做任何处理 **/
            if (msg.chatType==YNBubbleMessageChatTypeGroupChat||msg.chatType==YNBubbleMessageChatTypeDiscussion ||msg.chatType==YNBubbleMessageChatTypeProjectTeamChat ||msg.chatType==YNBubbleMessageChatTypeGroupChatVoice||msg.chatType==YNBubbleMessageChatTypeDiscussionVoice ||msg.chatType==YNBubbleMessageChatTypeProjectTeamVoice) {
                if ([[message from].resource isEqualToString:[YNIMmanager sharedInstance].userImId]) {
                    //判断该条消息是否是pc端同步过来的消息
                    NSTextCheckingResult *result = [YNIMTool regularMatchingTheString:msg.packetId regularString:@"^(Msg_PC_|msg_pc_)"];
                    if (!result) {
                        //不是以Msg_PC_或msg_pc_开头的，则说明不是pc端同步过来的需要过滤
                        return;
                    }
                }
            }
            if (msg.chatType==YNBubbleMessageChatTypeDocumentsSent) {
                /**HX** 过略掉文件p2p发送这条的捂手信息 **/
                return;
            }
            //需要本地通知
            BOOL needlocalNotification=YES;
            
            if ([chatType isEqualToString:@"groupchat"] || [chatType isEqualToString:@"chat"])
            {
                //消息提示音的时间
                [multicastDelegate updateSoundPlayTime];
                
                switch (msg.chatType) {
                        //                case YNBubbleMessageChatTypeWeChat:
                        //2016-7-14jc修改
                    case YNBubbleMessageChatTypeWeChat:
                    case YNBubbleMessageChatTypeWeChatVoice:
                    case YNBubbleMessageChatTypeFileWeChat:
                    {
                        //两人消息
                        if ([[message from].user isEqualToString:[YNIMmanager sharedInstance].userImId]) {
                            //自己在pc端发的消息
                            needlocalNotification=NO;
                            //如果是同步到pc端收文件回执的消息，得过滤掉
                            if (msg.chatType!=YNBubbleMessageChatTypeFileWeChat) {
                                [multicastDelegate receiveMessageFromUser:msg messageControType:YNBubbleMessageTypeSending];
                            }
                        }else{
                            [multicastDelegate receiveMessageFromUser:msg messageControType:YNBubbleMessageTypeReceiving];
                        }
                    }
                        break;
                        //2016-7-14jc修改
                    case YNBubbleMessageChatTypeGroupChat:
                    case YNBubbleMessageChatTypeDiscussion:
                    case YNBubbleMessageChatTypeProjectTeamChat:
                    case YNBubbleMessageChatTypeGroupChatVoice:
                    case YNBubbleMessageChatTypeDiscussionVoice:
                    case YNBubbleMessageChatTypeProjectTeamVoice:
                    {
                        if ([[message from].resource isEqualToString:[YNIMmanager sharedInstance].userImId]) {
                            //自己在pc端发的消息
                            needlocalNotification=NO;
                            [multicastDelegate receiveGroupMessage:msg messageControType:YNBubbleMessageTypeSending];
                        }else{
                            //判断是否开启免打扰
                            NSInteger messRemind = [YNIMmanager queryMessageRemindWithGroupID:msg.friendId];
                            if (messRemind == 0) {
                                needlocalNotification = NO;
                            }
                            [multicastDelegate receiveGroupMessage:msg messageControType:YNBubbleMessageTypeReceiving];
                        }
                    }
                        break;
                        
                    case YNBubbleMessageChatTypeBroadcast:
                    {
                        //广播消息
                        if (msg.messageMediaType==YNBubbleMessageLive) {
                            //视频会议开始的消息
                            needlocalNotification=NO;
                            dispatch_async(dispatch_get_main_queue(), ^{
                               [[NSNotificationCenter defaultCenter]postNotificationName:YNNotificationCloudOpenfirReciveMessage object:msg];
                            });
                        }else{
                            NSString *covertStr = [YNMessage covertJsonWithHTML:message.body];
                            NSDictionary *messageBody = (NSDictionary*)[YNIMTool getJsonObjectFromJsonString:covertStr];
                            
                            if (![messageBody isKindOfClass:[NSDictionary class]]) {
                                //为pc端发的广播需要做处理
                                [multicastDelegate receiveBroadcastMessage:msg];
                            }else{
                                if ([YNIMTool isEmptyObject:messageBody[@"messageType"]]) {
                                    //为pc端发的广播需要做处理
                                    [multicastDelegate receiveBroadcastMessage:msg];
                                }else{
                                    //为平台发出的推送消息广播不要做处理
                                    needlocalNotification=NO;
                                }
                            }
                        }
                        
                    }
                        break;
                        
                    case YNBubbleMessageChatTypeNotification:
                    {
                        debugLog(@"所有通知，都走阿里推送通知。不走xmpp推送了。");
                        
                        needlocalNotification=NO;
                        
                    }
                        break;
                        
                    default:
                    {

                        debugLog(@"其他类型消息");
                    }
                        break;
                }
            }
            
            //判断通知是否开启
            if ([YNMessagerManager isAllowedNotification])
            {
                if (needlocalNotification) {
                    //判断是不是在后台
                    if ([YNMessagerManager isApplicationStateActive])
                    {
                        NSDate *currentDate = [NSDate date];
                        NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:lastDate];
                        
                        if (timeInterval > NotificationTime)
                        {
                            localNotification.hasAction = YES;
                            localNotification.alertAction = NSLocalizedString(@"查看", nil);
                            
                            NSString *alertBody = nil;
                            //2017-6-6jc修改，当发送是图片，文件时，应显示[图片],[文件]
                            /**HX** 黄旭修改，空判断 **/
                            if (msg.friendName==nil||msg.friendName.length==0) {
                                msg.friendName=@"";
                            }
                            if(msg.messageMediaType == YNBubbleMessagePhoto)
                            {
                                alertBody = [NSString stringWithFormat:@"%@\n%@", msg.friendName,@"[图片]"];
                            }
                            else if (msg.messageMediaType == YNBubbleMessageFile)
                            {
                                alertBody = [NSString stringWithFormat:@"%@\n%@", msg.friendName,@"[文件]"];
                            }
                            else
                            {
                                //2018-11-23JC添加-解决发送艾特@时，消息通知把 [\@张三]->@张三
                                
                                NSString * body = [msg.body mutableCopy];
                                NSArray * array = [YNIMTool findAllMatchedText:body rexStr:kATRegularReturn];
                                if(![YNIMTool isEmptyArray:array])
                                {
                                    AitContactManagerTool * aitContactManager = [[AitContactManagerTool alloc]init];
                                    aitContactManager.groupNo = msg.friendId;
                                    body = [aitContactManager replaceMessageTextWithText:body];
                                    
                                }
                                /**HX** 消息通知把 [\1001]->[表情] **/
                                array=[YNIMTool findAllMatchedText:msg.body rexStr:kExpressionMessageMatch];
                                if (![YNIMTool isEmptyArray:array]) {
                                    for (NSTextCheckingResult*result in array) {
                                        body=[body stringByReplacingOccurrencesOfString:[msg.body substringWithRange:result.range] withString:@"[表情]"];
                                    }
                                }
                                
                                alertBody = [NSString stringWithFormat:@"%@\n%@", msg.friendName, body];
                            }
                            
                            localNotification.alertBody = NSLocalizedString(alertBody, nil);
                            localNotification.userInfo=@{@"isLocalNotification":@"1"};
                            
                            if ([UIApplication sharedApplication].applicationIconBadgeNumber != 99)
                            {
                                [UIApplication sharedApplication].applicationIconBadgeNumber++;
                            }
                            
                            [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
                            
                            lastDate = currentDate;
                        }
                        else
                        {
                            localNotification.hasAction = NO;
                            localNotification.alertAction = NSLocalizedString(@"查看", nil);
                            
                            NSString *alertBody = nil;
                            //2017-6-6jc修改，当发送是图片，文件时，应显示[图片],[文件]
                            /**HX** 黄旭修改，空判断 **/
                            if (msg.friendName==nil||msg.friendName.length==0) {
                                msg.friendName=@"";
                            }
                            if(msg.messageMediaType == YNBubbleMessagePhoto)
                            {
                                alertBody = [NSString stringWithFormat:@"%@\n%@", msg.friendName,@"[图片]"];
                            }
                            else if (msg.messageMediaType == YNBubbleMessageFile)
                            {
                                alertBody = [NSString stringWithFormat:@"%@\n%@", msg.friendName,@"[文件]"];
                            }
                            else
                            {
                                //2018-11-23JC添加-解决发送艾特@时，消息通知把 [\@张三]->@张三
                                NSString * body = [msg.body mutableCopy];
                                NSArray * array = [YNIMTool findAllMatchedText:body rexStr:kATRegularReturn];
                                if(![YNIMTool isEmptyArray:array])
                                {
                                    AitContactManagerTool * aitContactManager = [[AitContactManagerTool alloc]init];
                                    aitContactManager.groupNo = msg.friendId;
                                    body = [aitContactManager replaceMessageTextWithText:body];
                                    
                                }
                                /**HX** 消息通知把 [\1001]->[表情] **/
                                array=[YNIMTool findAllMatchedText:msg.body rexStr:kExpressionMessageMatch];
                                if (![YNIMTool isEmptyArray:array]) {
                                    for (NSTextCheckingResult*result in array) {
                                        body=[body stringByReplacingOccurrencesOfString:[msg.body substringWithRange:result.range] withString:@"[表情]"];
                                    }
                                }
                                alertBody = [NSString stringWithFormat:@"%@\n%@", msg.friendName, body];
                                
                            }
                            
                            
                            localNotification.alertBody = NSLocalizedString(alertBody, nil);
                            localNotification.userInfo=@{@"isLocalNotification":@"1"};
                            if ([UIApplication sharedApplication].applicationIconBadgeNumber != 99)
                            {
                                [UIApplication sharedApplication].applicationIconBadgeNumber++;
                            }
                            
                            [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
                            
                        }
                    }
                }
                
            }
            debugLog(@"聊天消息");
        }
        else if (message.subject && message.body == nil) //修改讨论组名称或群公告
        {
            
            //修改群/讨论组的用户ID
            NSString *groupName = [[message from] user];
            NSString *groupSubject = message.subject;
            
            int groupType=1;
            if ([groupName rangeOfString:DiscussionGroupFlag].length > 0) {
                groupType=kContact_DiscussionGropType;
            }else if ([groupName rangeOfString:UserGroupFlag].length > 0) {
                groupType=kContact_UserGroupType;
            }else{
                groupType=kContact_ProjectTeamGropType;
            }
            
            YNContactGroup *group = [YNContactManager queryGroupByGroupNo:groupName groupType:groupType];
            
            if (group)//如果群/讨论组存在
            {
                dispatch_async(dispatch_get_main_queue(), ^{
                    
                    group.naturalName = groupSubject;
                    group.subject = groupSubject;
                    group.groupType = groupType;
                    BOOL result = [YNContactManager updateContactGroup:group];
                    if (result)
                    {
                        if (([groupName rangeOfString:DiscussionGroupFlag].length > 0)) {
                            if ([self.delegate respondsToSelector:@selector(modifyDiscussionGroupName:)]) {
                                [self.delegate modifyDiscussionGroupName:groupName];
                            }
                        }else if (([groupName rangeOfString:UserGroupFlag].length > 0)){
                            if ([self.delegate respondsToSelector:@selector(modifyGroupName:)]) {
                                [self.delegate modifyGroupName:groupName];
                            };
                            
                        }
                    }
                    
                });
            }
        }
    }
   
}

/**
 2018-12-12JC添加
 撤回消息逻辑处理
 
 @param message
 */
-(void)messengerWithdrawunMarkInfowithMessage:(XMPPMessage *)message
{
    NSXMLElement *unmark = [message elementForName:@"unmark"];
    //撤回
    if(unmark != nil)
    {
        //        NSString * chatType =  [[unmark elementForName:@"chatType"] stringValue];//
        //        NSString * item =  [[unmark elementForName:@"item"] stringValue];//撤销人
        NSString * chatId =  [[unmark elementForName:@"chatId"] stringValue]; //会话id
        NSString * msgId =  [[unmark elementForName:@"msgId"] stringValue];//消息id
        
        CurrenChatObjType groupType = [YNMessagerReceiveHandle getCurrentMessageChatTypemanyPeopleChatWith:chatId];
        if(groupType == 0)
        {
            [YNMessageContactManager updateTwoPeopleChatWithdrawWithPackId:msgId];
        }
        else
        {
            
            [YNMessageContactManager updateManyPeopleMessageWithdrawWithPacketId:msgId groupType:groupType];
        }
        
        BOOL resultList = [YNMessageContactManager updateRecentChatWithdrawWithChatId:chatId packId:msgId];
        if(resultList)
        {
            dispatch_async(dispatch_get_main_queue(), ^{
                
                //通知更新消息列表UI
                if ([self.delegate respondsToSelector:@selector(updataRecentChatInterface)]) {
                    [self.delegate receiveChatMesWithRecentChatId:msgId userNo:nil];
                }
            });
        }
        
        
        dispatch_async(dispatch_get_main_queue(), ^{
            
            //通知更新聊天界面UI
            if ([self.delegate respondsToSelector:@selector(messengerChatWithDrawUpdateMsgId:success:)]) {
                [self.delegate messengerChatWithDrawUpdateMsgId:msgId success:YES];
            }
        });
        
        
    }
}


/**
 * 接受的消息回执
 * 在这里进行处理
 **/
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
{
    NSXMLElement *req = [iq elementForName:@"req"];
    
    if (req != nil)
    {
        NSString *xmlns = [req xmlns];
        if ([xmlns isEqualToString:@"com:yineng:receipt"])
        {
            [xmppIDTracker invokeForID:[iq elementID] withObject:iq];
        }
    }
    
    return YES;
}

- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
{
    NSXMLElement *xElement = [presence elementForName:@"x"];
    //判断是否是群和讨论组presence
    if (xElement)
    {
        //判断是退出，还是创建(其他人退出在消息管理类处理，其他人创建也是消息处理类里面管理)
        if ([presence.type isEqualToString:@"unavailable"])
        {
            //处理退出讨论的presence ,主动退出讨论组的回执
            NSString *jid = [[presence from] resource];
            NSString *groupName = [[presence from] user];
            YNUser *user = [[YNUser alloc] init];
            YNContactGroup *group = [[YNContactGroup alloc] init];
            user.userNo = jid;
            group.groupName = groupName;
            
            if ([jid isEqualToString:[YNIMmanager sharedInstance].userImId])
            {
                debugLog(@"退出群/讨论组");
                
                if ([groupName rangeOfString:DiscussionGroupFlag].length > 0)
                {
                    debugLog(@"离开讨论组");
                    
                    __block BOOL result;
                    dispatch_queue_t dispatchQueue = dispatch_queue_create("exit.leave.disgroup", DISPATCH_QUEUE_CONCURRENT);
                    dispatch_group_t dispatchGroup = dispatch_group_create();
                    dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
                        group.groupType = CurrenChatObjType_discussion;
                        result = [YNContactManager dissolveGroupByGroup:group];
                    });
                    dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
                        result = [YNContactManager deleteRecentChatWithRecentChatObject:groupName];
                    });
                    dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
                        debugLog(@"通知退出讨论组");
                        if (result)
                        {
                            if ([self.delegate respondsToSelector:@selector(leaveDiscussionGroupName:)]) {
                                [self.delegate leaveDiscussionGroupName:groupName];
                            }
                        }
                        
                    });
                    
                    
                }
                else if ([groupName rangeOfString:UserGroupFlag].length > 0)
                {
                    debugLog(@"离开群");
                    
                    __block BOOL result;
                    dispatch_queue_t dispatchQueue = dispatch_queue_create("exit.leave.group", DISPATCH_QUEUE_CONCURRENT);
                    dispatch_group_t dispatchGroup = dispatch_group_create();
                    dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
                        group.groupType = CurrenChatObjType_group;
                        result = [YNContactManager dissolveGroupByGroup:group];
                    });
                    dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
                        result = [YNContactManager deleteRecentChatWithRecentChatObject:groupName];
                    });
                    dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
                        
                        if (result)
                        {
                            if ([self.delegate respondsToSelector:@selector(leaveGroupName:)]) {
                                [self.delegate leaveGroupName:groupName];
                            }
                        }
                        
                    });
                }
                else
                {
                    debugLog(@"离开项目组");
                    __block BOOL result;
                    dispatch_queue_t dispatchQueue = dispatch_queue_create("exit.leave.projectTeam", DISPATCH_QUEUE_CONCURRENT);
                    dispatch_group_t dispatchGroup = dispatch_group_create();
                    dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
                        group.groupType = CurrenChatObjType_projectTeam;
                        result = [YNContactManager dissolveGroupByGroup:group];
                    });
                    dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
                        result = [YNContactManager deleteRecentChatWithRecentChatObject:groupName];
                    });
                    dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
                        
                        if (result)
                        {
                            if ([self.delegate respondsToSelector:@selector(leaveProjectTeamName:)]) {
                                [self.delegate leaveProjectTeamName:groupName];
                            }
                        }
                        
                    });
                }
                
            }
            else
            {
                //讨论组中其他成员退出
                if ([groupName rangeOfString:DiscussionGroupFlag].length > 0)
                {
                    
                    debugLog(@"其他讨论组成员退出讨论组");
                    
                    __block BOOL result;
                    dispatch_queue_t dispatchQueue = dispatch_queue_create("exit.disgroup", DISPATCH_QUEUE_CONCURRENT);
                    dispatch_group_t dispatchGroup = dispatch_group_create();
                    dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
                        result = [YNContactManager leaveGroupWithUser:user group:group];
                    });
                    
                    dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
                        debugLog(@"通知其他讨论组成员退出讨论组");
                        if (result)
                        {
                            if ([self.delegate respondsToSelector:@selector(exitDiscussionGroupName:)]) {
                                [self.delegate exitDiscussionGroupName:groupName];
                            }
                        }
                        
                    });
                }
                else if ([groupName rangeOfString:UserGroupFlag].length > 0)//群其他成员退出
                {
                    
                    debugLog(@"其他成员退出群群");
                    
                    __block BOOL result;
                    dispatch_queue_t dispatchQueue = dispatch_queue_create("exit.group", DISPATCH_QUEUE_CONCURRENT);
                    dispatch_group_t dispatchGroup = dispatch_group_create();
                    dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
                        result = [YNContactManager leaveGroupWithUser:user group:group];
                    });
                    
                    dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
                        debugLog(@"通知其他群成员离开群");
                        if (result)
                        {
                            if ([self.delegate respondsToSelector:@selector(exitGroupName:)]) {
                                [self.delegate exitGroupName:groupName];
                            }
                        }
                        
                    });
                }
                else//项目组其他成员退出
                {
                    debugLog(@"其他成员退出项目组");
                    
                    __block BOOL result;
                    dispatch_queue_t dispatchQueue = dispatch_queue_create("exit.projectTeam", DISPATCH_QUEUE_CONCURRENT);
                    dispatch_group_t dispatchGroup = dispatch_group_create();
                    dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
                        result = [YNContactManager leaveGroupWithUser:user group:group];
                    });
                    
                    dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
                        debugLog(@"通知其他项目组成员离开项目组");
                        if (result)
                        {
                            if ([self.delegate respondsToSelector:@selector(exitProjectTeamGroupName:)]) {
                                [self.delegate exitProjectTeamGroupName:groupName];
                            }
                        }
                        
                    });
                }
            }
        }
        else
        {
            
            // NSXMLElement *status = [xElement elementForName:@"status"];
            
            NSString *jid = [[presence from] resource];
            NSString *groupName = [[presence from] user];
            
            //判断是否为讨论组
            if ([groupName rangeOfString:DiscussionGroupFlag].length > 0)
            {
                //debugLog(@"讨论组");
                BOOL result = [YNContactManager whetherGroupOfMembers:jid withGroupNo:groupName groupType: kContact_DiscussionGropType];
                if (!result)
                {
                    [YNRemindManager saveNewGroupRemind:groupName];
                    [[YNIMmanager sharedInstance]getDiscussionInfoWithDiscussionName:groupName];
                }
                
            }
            else if([groupName rangeOfString:UserGroupFlag].length > 0) //群
            {
                BOOL result = [YNContactManager whetherGroupOfMembers:jid withGroupNo:groupName groupType:kContact_UserGroupType];
                if (!result)
                {
                    [[YNIMmanager sharedInstance] getGroupInfoWithGoupName:groupName];
                }
            }
            else //项目组
            {
                BOOL result = [YNContactManager whetherGroupOfMembers:jid withGroupNo:groupName groupType:kContact_ProjectTeamGropType];
                if (!result)
                {
                    [[YNIMmanager sharedInstance] getProjectTeamInfoWithTeamName:groupName];
                }
            }
            
        }
        
    }
    else
    {
        if ([presence.type isEqualToString:@"unavailable"])//用户状态(离线)
        {
            __block NSString *resource = [[presence from] resource];
            __block YNUser *user = [[YNUser alloc] init];
            user.userNo = [[presence from] user];
            
            dispatch_queue_t dispatchQueue = dispatch_queue_create("exit.logout", DISPATCH_QUEUE_CONCURRENT);
            dispatch_group_t dispatchGroup = dispatch_group_create();
            __block BOOL result ;
            dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
                //将user通过本地数据赋值，拿到它之前的在线状态
                user = [YNContactManager queryUserNameByUserID:user.userNo chatType:YNBubbleMessageChatTypeWeChat];
                if ([resource isEqualToString:kResource_Msg_PC])
                {
                    user.pcStatus = nil;
                    result =[YNContactManager updateUserStatus:user updatePcStatus:YES updatePhoneStatus:NO];
                }
                else if([resource isEqualToString:kResource_Msg_Phone])
                {
                    user.phoneStatus = nil;
                    result =[YNContactManager updateUserStatus:user updatePcStatus:NO updatePhoneStatus:YES];
                    
                }
            });
            dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
                
                if (result)
                {
                    if ([self.delegate respondsToSelector:@selector(xmppIMuserLogout:)]) {
                        [self.delegate xmppIMuserLogout:user];
                    }
                }
                
            });
            
        }
        
        //2016-11-16jc添加
        //用户在线
        else
        {
            __block NSString *statusString = kResource_Online_Phone_PC;
            __block NSString *resource = [[presence from] resource];
            __block YNUser *user = [[YNUser alloc] init];
            user.userNo = [[presence from] user];
            
            dispatch_queue_t dispatchQueue = dispatch_queue_create("login", DISPATCH_QUEUE_CONCURRENT);
            dispatch_group_t dispatchGroup = dispatch_group_create();
            __block BOOL result ;
            dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
                //将user通过本地数据赋值，拿到它之前的在线状态
                user = [YNContactManager queryUserNameByUserID:user.userNo chatType:YNBubbleMessageChatTypeWeChat];
                if ([resource isEqualToString:kResource_Msg_PC])
                {
                    user.pcStatus = statusString;
                    result =[YNContactManager updateUserStatus:user updatePcStatus:YES updatePhoneStatus:NO];
                }
                else if([resource isEqualToString:kResource_Msg_Phone])
                {
                    user.phoneStatus = statusString;
                    result =[YNContactManager updateUserStatus:user updatePcStatus:NO updatePhoneStatus:YES];
                }
            });
            dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
                
                if (result)
                {
                    if ([self.delegate respondsToSelector:@selector(xmppIMuserLogin:)]) {
                        [self.delegate xmppIMuserLogin:user];
                    }
                }
                
                
            });
        }
    }
}


//查询群信息回调
- (void)reciveGroupInfo:(NSDictionary *)dic
{
    
    debugLog(@"群创建或添加成员");
    if([YNIMTool isEmptyDictionary:dic])
    {
        debugLog(@"error:查询群信息回调为空");
        return;
        
    }
    
    debugLog(@"群创建或添加成员");
    NSArray * roomList = [dic objectForKey:@"roomList"];
    
    if([YNIMTool isEmptyArray:roomList])
    {
        debugLog(@"error:查询群信息回调为空");
        return;
    }
    
    
    NSDictionary *roomListDic = [roomList firstObject];
    
    NSString *groupName = [roomListDic objectForKey:@"groupName"];
    
    dispatch_sync(dispatch_get_global_queue(0, 0), ^{
        
        [YNContactManager saveIncrementalGroupDataWithDictionary:dic groupType:kContact_UserGroupType];
        
        dispatch_async(dispatch_get_main_queue(), ^{
            
            if ([self.delegate respondsToSelector:@selector(updateGroupName:)]) {
                [self.delegate updateGroupName:groupName];
            }
            
        });
        
    });
}

//查询讨论组信息回调
- (void)reciveDiscussionInfo:(NSDictionary *)dic
{
    if([YNIMTool isEmptyDictionary:dic])
    {
        debugLog(@"error:查询讨论组信息回调为空");
        return;
    }
    
    NSArray * roomList = [dic objectForKey:@"roomList"];
    
    if([YNIMTool isEmptyArray:roomList])
    {
        debugLog(@"error:查询讨论组信息回调为空");
        return;
    }
    
    
    NSDictionary *roomListDic = [roomList firstObject];
    
    NSString *groupName = [roomListDic objectForKey:@"groupName"];
    
    
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_sync(globalQueue, ^{
        
        [YNContactManager saveIncrementalGroupDataWithDictionary:dic groupType:kContact_DiscussionGropType];
        
        //在主线程中刷新
        dispatch_async(dispatch_get_main_queue(), ^{
            
            if ([self.delegate respondsToSelector:@selector(updateDiscussionGroupName:)]) {
                [self.delegate updateDiscussionGroupName:groupName];
            }
            
        });
        
    });
    
}
//查询项目组信息回调
- (void)reciveProjectTeamInfo:(NSDictionary *)dic
{
    if([YNIMTool isEmptyDictionary:dic])
    {
        debugLog(@"error:查询项目组信息回调为空啦");
        return;
    }
    NSArray * roomList = [dic objectForKey:@"roomList"];
    if([YNIMTool isEmptyArray:roomList])
    {
        debugLog(@"error:查询项目组信息回调为空啦");
        return;
    }

    
    NSDictionary *roomListDic = [roomList firstObject];
    
    NSString *groupName = [roomListDic objectForKey:@"groupName"];
    
    
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_sync(globalQueue, ^{
        
        [YNContactManager saveIncrementalGroupDataWithDictionary:dic groupType:kContact_ProjectTeamGropType];
        
        //在主线程中刷新
        dispatch_async(dispatch_get_main_queue(), ^{
            
            if ([self.delegate respondsToSelector:@selector(updateProjectTeamGroupName:)]) {
                [self.delegate updateProjectTeamGroupName:groupName];
            }
            
        });
        
    });
    
}

#pragma mark - receipt mothed

//在没有对象实现代理的情况下，收到消息回执在这里处理
- (void)receiveReceiptWithIQ:(XMPPIQ *)iq aMessage:(YNMessage *)message
{
    if (iq)
    {
        //iq不为空，消息有回执，发送成功
        //更改状态
        message.sendState = YNMessageSendStateSuccess;
        
        //成功
        NSXMLElement *req = [iq elementForName:@"req"];
        NSString *sendTime = [[req elementForName:@"sendTime"] stringValue];
        
        message.sendTime = sendTime;
        
        //更新数据库
        [YNMessageContactManager updateChatWithMessage:message changRecentChat:NO];
        
        message.currentTime = [self dateStringFromMINDate:sendTime];
    }
    else
    {
        //发送失败
        message.sendState = YNMessageSendStateFailed;
        
        //更新数据库
        [YNMessageContactManager updateChatWithMessage:message changRecentChat:NO];
    }
    //通知更新会话界面
    dispatch_async(dispatch_get_main_queue(), ^{
        if ([self.delegate respondsToSelector:@selector(updataRecentChatInterface)]) {
            [self.delegate receiveChatMesWithRecentChatId:message.packetId userNo:message.toUserId];
        }
        if ([self.delegate respondsToSelector:@selector(receiveMessageReceipt:)]) {
            [self.delegate receiveMessageReceipt:message];
        }
    });
}

//获取发送时间
- (NSString *)dateStringFromMINDate:(NSString *)time
{
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss.SSS"];
    if (time)
    {
        NSDate *date = [dateFormatter dateFromString:time];
        if (date == nil)
        {
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            date = [dateFormatter dateFromString:time];
        }
        [dateFormatter setDateFormat:@"HH:mm"];
        NSString *serverTime = [dateFormatter stringFromDate:date];
        return serverTime;
    }
    else
    {
        NSString *localityTime = [dateFormatter stringFromDate:[NSDate date]];
        return localityTime;
    }
}
//判断用户是否开启了通知
+ (BOOL)isAllowedNotification
{
    dispatch_semaphore_t querySemaphore = dispatch_semaphore_create(0);
    __block BOOL result = NO;
    dispatch_async(dispatch_get_main_queue(), ^{
        UIUserNotificationSettings *setting = [[UIApplication sharedApplication] currentUserNotificationSettings];
        if (UIUserNotificationTypeNone != setting.types)
        {
            result = YES;
        }
        dispatch_semaphore_signal(querySemaphore);
    });
    
    dispatch_semaphore_wait(querySemaphore, DISPATCH_TIME_FOREVER);
    return result;
}
//判断是否在后台
+(BOOL)isApplicationStateActive{
    dispatch_semaphore_t querySemaphore = dispatch_semaphore_create(0);
    
    __block BOOL result = NO;
    dispatch_async(dispatch_get_main_queue(), ^{
        result = [[UIApplication sharedApplication] applicationState] != UIApplicationStateActive;
        dispatch_semaphore_signal(querySemaphore);
    });
    
    dispatch_semaphore_wait(querySemaphore, DISPATCH_TIME_FOREVER);
    return result;
}

#pragma end
@end
